<template>
  <n-layout class="app-main" :has-sider="true">
    <!-- 侧边菜单 -->
    <n-layout-sider
        class="menu-layout"
        collapse-mode="width"
        :collapsed="collapsed"
        :collapsed-width="64"
        @collapse="collapsed = true"
        @expand="collapsed = false"
        show-trigger
        :width="200"
        bordered
    >
      <div class="user-panel" v-if="userStore.token != null" :style="collapsed ? {height: '3rem'} : {}" >
        <n-avatar round :size="collapsed ? 30 : 60">
          {{ userStore.username.substring(0, 1) }}
        </n-avatar>

        <n-h3 v-if="!collapsed" class="name" style="margin: 5px 0 0 0;">
          {{ userStore.username }}
        </n-h3>
      </div>
      <div class="user-panel" style="cursor: pointer" @click="toLogin" v-else>
        <n-avatar round :size="collapsed ? 30 : 60">
          <span :style="{fontSize: collapsed ? '12px': '16px' }">登录</span>
        </n-avatar>

        <n-h3 v-if="!collapsed" class="name" style="margin: 5px 0 0 0;">点击登录</n-h3>
      </div>

      <n-menu
          class="menu"
          :collapsed="collapsed"
          :collapsed-width="64"
          :collapsed-icon-size="22"
          :options="getMenu()"
          :value="menuValue"
          @update:value="menuOptionsOnChange"
          :style="{maxHeight: collapsed ? 'calc(100vh - 3rem)' : 'calc(100vh - 6rem)'}"
      />
    </n-layout-sider>

    <!-- 内容区 -->
    <n-layout-content content-style="padding: 24px" :native-scrollbar="false">
      <router-view></router-view>
    </n-layout-content>
  </n-layout>
</template>

<script>
import IconHome from '@/components/icons/IconHome.vue'
import IconLogout from '@/components/icons/IconLogout.vue'
import IconUserProfile from '@/components/icons/IconUserProfile.vue'
import IconTopic from '@/components/icons/IconTopic.vue'

import {NIcon, useDialog, useLoadingBar} from "naive-ui";
import {h, ref, computed} from "vue";
import {useUserStore} from "@/stores/user";
import {useRoute, useRouter} from "vue-router";
import {useRequests} from "@/common/requests.js";
import {useIsMobile} from "@/common/composables.js";

export default {
  name: "LayoutView",
  setup() {
    const route = useRoute()
    const router = useRouter()
    const loadingBar = useLoadingBar()
    const userStore = useUserStore()
    const requests = useRequests()

    router.beforeEach((to, from) => {
      // 登录检测
      if (!['NotFound', 'PermissionDenied', 'home', 'UserLogin', 'UserLoginPage'].includes(to.name) && to.path !== from.path) {
        const isLogin = computed(() => userStore.token !== null).value;
        if (!isLogin) {
          router.push({name: 'UserLogin'})
        }
      }

      if (to.path !== from.path) {
        loadingBar.start()
      }

      rerenderMenuOption(to.path)
    })

    router.afterEach((to, from, failure) => {
      if (to.path !== from.path) {
        if (failure) {
          loadingBar.error()
        } else {
          loadingBar.finish()
        }
      }
    })

    const dialog = useDialog()
    const collapsed = ref(useIsMobile())

    const renderIcon = (icon) => {
      return () => h(NIcon, null, { default: () => h(icon) })
    }

    const logout = () => {
      dialog.create({
        closable: false,
        showIcon: null,
        title: '确定要退出吗？',
        content: '退出后将注销登录并返回首页',
        positiveText: '继续退出',
        negativeText: '取消',
        onPositiveClick: () => {
          userStore.$reset()
          router.push('/')
        }
      })
    }

    const menuValue = ref('home')
    const menuOptions = [
      {
        label: '首页',
        icon: renderIcon(IconHome),
        key: 'home',
        path: ''
      },
      {
        label: '话题',
        icon: renderIcon(IconTopic),
        key: 'topic',
        path: 'topic/list'
      },
      {
        label: '个人中心',
        icon: renderIcon(IconUserProfile),
        key: 'user',
        path: 'user',
        render() {
          return userStore.token != null
        }
      },
      {
        label: '退出',
        icon: renderIcon(IconLogout),
        key: 'logout',
        func: logout,
        render() {
          return userStore.token != null
        }
      },
    ]

    const getMenu = () => {
      const list = menuOptions.filter(item => {
        if (typeof item.render == 'function') {
          return item.render()
        } else {
          return true
        }
      })
      return list
    }

    const menuOptionsOnChange = (key, item) => {
      if (item.path !== undefined) {
        const path = '/' + item.path
        if (route.path !== path) {
          router.push({path})
        }
      } else {
        item.func !== undefined && item.func()
      }
    }

    const rerenderMenuOption = path => {
      // 去除第一个斜杠
      const index = path.indexOf('/')
      if (index !== -1) {
        path = path.substring(index + 1)
      }

      // 首次加载时判断当前选中的菜单
      for (const item of menuOptions) {
        if (item.path === path) {
          return menuValue.value = item.key
        }
      }
    }

    const toLogin = () => {
      router.push({name: 'UserLoginPage'})
    }

    requests.user.checkLogin().then(resp => {
      if (resp.ret === 0) {
        requests.profile.getMe().then(resp => {
          if (resp.ret === 0) {
            userStore.$patch({profile: resp.data})
          }
        })
        requests.user.meta().then(resp => {
          if (resp.ret === 0) {
            userStore.$patch({
              role: resp.data.role,
              status: resp.data.status
            })
          }
        })
      }
    })

    return {
      userStore,
      collapsed,
      menuValue,
      getMenu,
      menuOptionsOnChange,
      toLogin
    }
  }
}
</script>

<style lang="scss" scoped>
* {
  --bar-border-color: rgba(255, 255, 255, 0.09);
  --van-popup-close-icon-z-index: 100;
  --body-padding: 16px 24px;
}

*:not(input) {
  -webkit-user-select: none;
  user-select: none;
}

.selectable, .selectable * {
  -webkit-user-select: auto;
  user-select: auto;
}

.unselectable, .unselectable * {
  -webkit-user-select: none;
  user-select: none;
}

.app-main {
  margin: 0;
  padding: 0;
  width: 100vw;
  height: 100vh;

  .menu-layout {

    .user-panel {
      height: 8rem;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;

      .avatar {
        position: relative;
        width: 60px;
        height: 60px;

        .wait-review, .review-reject {
          position: absolute;
          display: flex;
          align-items: center;
          justify-content: center;
          top: 0;
          left: 0;
          width: 100%;
          height: 100%;
          background-color: rgba(0, 0, 0, .7);
          color: #fff;
          border-radius: 50%;
          font-size: 13px;
          font-weight: normal;
          white-space: nowrap;
          overflow: hidden;
        }

        .review-reject {
          color: #f00
        }
      }

      .name {
        width: 75%;
        text-align: center;
        transition: all ease .3s;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }
    }

    .menu {
      max-height: calc(100vh - 8rem);
    }
  }
}
</style>
